#!/usr/bin/\env python
# -*- encoding: utf-8 -*-

import os
import sys
from xml.dom import minidom
import time
import glob
import re
import tempfile

import linkparse
import wordtable


FILENAME = 0
FILEPATH = 1
FILEICON = 2

class LnkManage:
    __DIRPATH = 0
    __DIRMODIFYTIME = 1
    __DIRlNKS = 2
    def __init__(self, bmpdir='bmp'):
        self.sysdirlnks = [] # [['', '', []], ]
        self.userlnks = ['', '', []]
        self.__doc = None
        
                
        # 先设置图标临时存放的目录
        self.bmpdir = bmpdir
        if self.bmpdir and not os.path.exists(self.bmpdir):
            os.mkdir(self.bmpdir)
            
                 
        pass
    def __reset(self):
        self.sysdirlnks = [] # [['', '', []], ]
        self.userlnks = ['', '', []]
        self.__doc = None
        
    def __addLnkFile(self, filePath):
        filename = ''
        fileTargetPath = ''
        filebmp = ''

        # 先取文件名
        filename = os.path.splitext(os.path.split(filePath)[1])[0]
        #print filename
        # 再取文件路径
        if self.__fileislnk(filePath):
            fileTargetPath = linkparse.GetpathFromLink(filePath)            
        else:
            fileTargetPath = filePath
        #print fileTargetPath
        # 判断文件是否存在，不存在那就不添加
        if not os.path.exists(fileTargetPath) or self.isDuplicateLnk(filename, fileTargetPath):
            return None
        if self.bmpdir:
            filebmp = os.path.join(self.bmpdir, filename + '.bmp')
            if not linkparse.ExtractIcon2File(fileTargetPath, filebmp):
                filebmp = ''
        return (filename, fileTargetPath, filebmp)

    def __addLnkDir(self, dir):
        lnks = []
        for root,dirs,files in os.walk(dir):
            #if not dirs and files:
            if files:
                for file in files:
                    lnk = self.__addLnkFile(os.path.join(root, file))
                    if lnk: lnks.append(lnk)
        return lnks

    def __fileislnk(self, filepath):
        fileheader = ''
        file = open(filepath, 'rb')
        fileheader = file.read(4)
        file.close()
        if fileheader == 'L\x00\x00\x00':
            return True
        else:
            return False
    
    def __getDirTime(self, dir):
        '''获取xml文件中sysdir中目录的最后修改时间，首选需要loadXml
        如果该目录存在，那么返回最后修改时间
        如果该目录不存在，返回None
        '''
        for lnks in self.sysdirlnks:
            if lnks[self.__DIRPATH] == dir:
                return lnks[self.__DIRMODIFYTIME]
        return None        
        pass

    def checkDirIsUpdate(self, dir, xmlfile):
        '''比较目录和xml文件,检查目录是否已经更新
        return True和False'''
        xmltime = ''
        dirmodifytime = time.ctime(os.path.getmtime(dir))
        xmldoc = minidom.parse(xmlfile)
        root = xmldoc.documentElement
#        for node in root.childNodes:
#            if node.nodeName == 'DIRINFO':
#                xmltime = node.getAttribute('lastmodifytime')
#                break
        if xmltime == dirmodifytime:
            return False
        else:
            return True

    def addLnk(self, path):
        """添加文件信息
        path可以是文件，也可以是目录
        path需要是unicode格式字符串
        """
        #print 'addLnk:', path
        ret = False
        if os.path.isdir(path):
            lnkinfo = ['', '', []]
            lnkinfo[self.__DIRPATH] = path
            lnkinfo[self.__DIRMODIFYTIME] = time.ctime(os.path.getmtime(path)).decode('utf-8')
            
            # 判断这个目录是否已经存在，获取最后修改时间
            # 如果最后修改时间一样，那就不用添加了
            lastTime = self.__getDirTime(path)
            if lastTime == None or lastTime != lnkinfo[self.__DIRMODIFYTIME]:
                lnkinfo[self.__DIRlNKS] = self.__addLnkDir(path)

                for sysdirlnk in self.sysdirlnks:
                    if sysdirlnk[self.__DIRPATH] != lnkinfo[self.__DIRPATH]:
                        continue
                    sysdirlnk[self.__DIRMODIFYTIME] = lnkinfo[self.__DIRMODIFYTIME]
                    sysdirlnk[self.__DIRlNKS] = (lnkinfo[self.__DIRlNKS])
                    break                                        
                else:               
                    self.sysdirlnks.append(lnkinfo)
                ret = True
        else:
            lnkinfo = self.__addLnkFile(path)
            if lnkinfo and lnkinfo not in self.userlnks[self.__DIRlNKS]:
                self.userlnks[self.__DIRlNKS].append(lnkinfo)
                ret = True
        return ret
            
    def isDuplicateLnk(self, filename, fileTargetPath):
        '''判断这个链接是否已经存在'''
        if (filename, fileTargetPath) in self.userlnks[self.__DIRlNKS]:
            return True
        for lnks in self.sysdirlnks:
            if (filename, fileTargetPath) in lnks[self.__DIRlNKS]:
                return True
        return False

    def __readNode(self, sysNode):
        dirlnkinfo = ['', '', []]
        for node in sysNode.childNodes:
            if node.nodeName == 'DirInfo':
                dirlnkinfo[self.__DIRPATH] = node.getAttribute('dirpath')
                dirlnkinfo[self.__DIRMODIFYTIME] = node.getAttribute('lastmodifytime')
            elif node.nodeName == 'LNK':                
                for lnk in [lnknode for lnknode in node.childNodes if lnknode.nodeName == 'A']:
                    filename = lnk.getAttribute('filename')
                    filepath = lnk.getAttribute('filepath')
                    fileicon = lnk.getAttribute('fileicon')                    
                    dirlnkinfo[self.__DIRlNKS].append((filename, filepath, fileicon))
        return dirlnkinfo

    def __readUserNode(self, userNode):
        if userNode.nodeName != 'UserNode':
            return
    def removeLNK(self, filename, filepath, fileicon):
        '''先load一个xml文件，再removeLNK， 在savexml文件
        '''
        for dirinfo in self.sysdirlnks:
            if (filename, filepath, fileicon) in dirinfo[self.__DIRlNKS]:
                dirinfo[self.__DIRlNKS].remove((filename, filepath, fileicon))
        if (filename, filepath, fileicon) in self.userlnks[self.__DIRlNKS]:
                self.userlnks[self.__DIRlNKS].remove((filename, filepath, fileicon))
        

    def loadXml(self, xmlfile):
        self.__reset()
        xml = minidom.parse(xmlfile)
        rootNode = xml.documentElement
        for node in rootNode.childNodes:
            if node.nodeName == 'SysNode':
                self.sysdirlnks.append(self.__readNode(node))
            elif node.nodeName == 'UserNode':
                self.userlnks = self.__readNode(node)      

    def createXml(self):
        self.__doc = minidom.Document()
        pass
    def __addSysNode(self, rootNode, dirLnks):
        """添加一个目录节点
        ['目录路径', '最后修改时间', [('链接名字'， '路径'),]]
        """
        sysNode = self.__doc.createElement('SysNode')
        # 添加文件信息
        dirInfo = self.__doc.createElement('DirInfo')
        dirInfo.setAttribute('dirpath', dirLnks[self.__DIRPATH].encode('utf-8'))
        dirInfo.setAttribute('lastmodifytime', dirLnks[self.__DIRMODIFYTIME].encode('utf-8'))
        sysNode.appendChild(dirInfo)
        # 添加链接
        lnkNode = self.__doc.createElement('LNK')
        sysNode.appendChild(lnkNode)
        for lnkinfo in dirLnks[self.__DIRlNKS]:
            node = self.__doc.createElement('A')
            node.setAttribute('fileicon', lnkinfo[FILEICON].encode('utf-8'))
            node.setAttribute('filepath', lnkinfo[FILEPATH].encode('utf-8'))
            node.setAttribute('filename', lnkinfo[FILENAME].encode('utf-8'))
            lnkNode.appendChild(node)
        rootNode.appendChild(sysNode)

    def __addUserNode(self, rootNode, dirLnks):
        """添加一个用户目录节点
        ['目录路径', '最后修改时间', [('链接名字'， '路径'),]]
        """
        userNode = self.__doc.createElement('UserNode')
        

        # 添加链接
        lnkNode = self.__doc.createElement('LNK')
        userNode.appendChild(lnkNode)
        for lnkinfo in dirLnks[self.__DIRlNKS]:
            node = self.__doc.createElement('A')
            node.setAttribute('fileicon', lnkinfo[FILEICON].encode('utf-8'))
            node.setAttribute('filepath', lnkinfo[FILEPATH].encode('utf-8'))
            node.setAttribute('filename', lnkinfo[FILENAME].encode('utf-8'))
            lnkNode.appendChild(node)
        rootNode.appendChild(userNode)


    def saveXml(self, xmlfile):
        """把添加的所有链接信息写入xml文件
        """
        if self.__doc == None:
            print '请先调用createXml'
            return
        # 创建主节点
        rootNode = self.__doc.createElement('Ooooo')
        self.__doc.appendChild(rootNode)

        for lnks in self.sysdirlnks:
            self.__addSysNode(rootNode, lnks)
        self.__addUserNode(rootNode, self.userlnks)
        f = open(xmlfile, 'w')
        self.__doc.writexml(f, "", "\t", "\n", "utf-8")
        f.close()
        pass

    def FindLnk(self, input):
        '''通过输入信息查找匹配的连接信息
        return 词典,{文件名字:(文件链接路径, 文件原始路径)...}
        '''
        inputpinyin = wordtable.Hanzi2PinYin(input).lower()
        # 正则表达式
        pattern = '^.*'
        for c in inputpinyin: pattern += "%s.*" % c
        pattern += '$'

        lnks = []

        for l in [lnk[self.__DIRlNKS] for lnk in self.sysdirlnks]:
            lnks.extend(l)
        if self.userlnks[self.__DIRlNKS]:
            lnks.extend(self.userlnks[self.__DIRlNKS])

        findResults = {} # 保存查找的结果
        for lnkinfo in lnks:
            #print lnkinfo
            res = re.findall(pattern, lnkinfo[FILENAME])
            if not res:
                pinyins = wordtable.Hanzi2PinYin(lnkinfo[FILENAME]).lower()
                res = re.findall(pattern, pinyins)
            if res:
                findResults[lnkinfo[FILENAME]] = (lnkinfo[FILEPATH], lnkinfo[FILEICON])      
                
        return findResults

if __name__ == '__main__':
    lm = LnkManage(bmpdir=r'E:\WingIDEPro\Ooooo\bmp')
    lm.loadXml(r'E:\WingIDEPro\Ooooo\Ooooo.xml'.decode('utf-8'))
    #lm.addLnk(r'C:\ProgramData\Microsoft\Windows\Start Menu'.decode('utf-8'))
    #lm.addLnk(r'C:\Users\lenovo\Desktop\Gidot Box.lnk'.decode('utf-8'))
    lm.addLnk(r'E:\Project\python\hello.xrc'.decode('utf-8'))
#    lm.addLnk(r'E:\Project\python\Ooooo\test.xml'.decode('utf-8'))
#    lm.addLnk(r'E:\Project\python\Ooooo\test.xml'.decode('utf-8'))
#    print lm.sysdirlnks
    lm.createXml();
    lm.saveXml(r'E:\WingIDEPro\Ooooo\Ooooo.xml'.decode('utf-8'))
#    pass
#    lm.loadXml(r'E:\WingIDEPro\Ooooo\test.xml'.decode('utf-8'))
#    lm.removeLNK("test", r"E:\Project\python\Ooooo\test.xml")
#    lm.createXml();
#    lm.saveXml(r'E:\Project\python\Ooooo\test.xml'.decode('utf-8'))
#    print lm.userlnks
#    lnks = lm.FindLnk('qq')
    #for l in lnks.keys():
        #print l
#    print lnks
    print 'exit'